package com.example.zjx8969.myapplication

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.text.TextUtils
import kotlinx.coroutines.*
import okio.buffer
import okio.source
import java.io.File
import java.lang.reflect.Type

fun loadStyle(context: Context, name: String): ByteArray {
    if (TextUtils.isEmpty(name)) return ByteArray(0)
    return when (File(name).exists()) {
        true -> File(name).source().buffer().use { it.readByteArray() }
        false -> context.assets.open(name).source().buffer().use { it.readByteArray() }
    }

}

inline fun <reified T> loadData(path: String, typeOfT: Type, scope:
CoroutineScope = CoroutineScope(Dispatchers.Default), crossinline operate: (t: T) -> Unit
) {
    scope.launch {
        val task = async(Dispatchers.IO) {
            try {
                val utf8 = File(path).source().buffer().use { it.readByteString().utf8() }
                return@async GsonAgent.getInstance().gson.fromJson<Any>(utf8, typeOfT)
            } catch (e: Exception) {
                return@async null
            }
        }

        val t: T = task.await() as T
        withContext(Dispatchers.Main) {
            operate(t)
        }
    }


}


suspend inline fun <reified T> loadData(assets: AssetManager, path: String, typeOfT: Type, crossinline operate: (t: T?) -> Unit) = coroutineScope {
    val t: T? = withContext(Dispatchers.IO) {

        try {
            val utf8 = assets.open(path).source().buffer().use {
                it.readByteString().utf8()
            }
            GsonAgent.getInstance().gson.fromJson<T>(utf8, typeOfT)
        } catch (e: Exception) {
            null
        }
    }
    withContext(Dispatchers.Main) {
        operate(t)
    }
}

suspend inline fun <reified T> loadData(assets: AssetManager, path: String, typeOfT: Type): T? {
    return withContext(Dispatchers.IO) {
        try {
            val utf8 = assets.open(path).source().buffer().use {
                it.readByteString().utf8()
            }
            GsonAgent.getInstance().gson.fromJson<T>(utf8, typeOfT)
        } catch (e: Exception) {
            null
        }
    }

}

suspend inline fun <reified T> loadLocalData(path: String, typeOfT: Type, crossinline operate: (t: T?) -> Unit) = coroutineScope {
    val task = async(Dispatchers.IO) {
        try {
            val utf8 = File(path).source().buffer().use { it.readByteString().utf8() }
            GsonAgent.getInstance().gson.fromJson<T>(utf8, typeOfT)
        } catch (e: Exception) {
            null
        }
    }
    val t: T? = task.await() //as T
    withContext(Dispatchers.Main) {
        operate(t)
    }
}

inline fun <reified T : Activity> Context.startActivity(vararg pair: Pair<String, String>) {
    val intent = Intent(this, T::class.java)
    pair.forEach { intent.putExtra(it.first, it.second) }
    startActivity(intent)
}

fun testFunction(x: Int, y: Int, operate: (a: Int, b: Int) -> Int): Int {
    return operate(x, y)
}